Preserve interception for offline Docker agents#1841
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 07e5e51513
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ApprovabilityVerdict: Needs human review This PR introduces significant new Docker networking infrastructure with network policies and egress control. Three unresolved review comments identify high-severity bugs: incorrect bridge gateway resolution, timing issues with interception host computation, and an attribute rename breaking shared tools functionality. You can customize Macroscope's approvability policy. Learn more. |
# Conflicts: # verifiers/v1/ARCHITECTURE.md # verifiers/v1/GUIDE.md # verifiers/v1/interception/pool.py # verifiers/v1/interception/server.py # verifiers/v1/rollout.py # verifiers/v1/runtimes/__init__.py # verifiers/v1/runtimes/base.py # verifiers/v1/runtimes/docker.py
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b1ac94fc1e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
# Conflicts: # verifiers/v1/runtimes/docker.py
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 81fed07. Configure here.
| "could not resolve the Docker host gateway: " | ||
| f"{(result.stderr or result.stdout).strip()}" | ||
| ) | ||
| return gateway |
There was a problem hiding this comment.
Wrong Docker bridge gateway
High Severity
With network_access=False, the harness joins a per-runtime setup bridge, but docker_interception_host() reads the default bridge network gateway. That IP usually differs from the setup network gateway, so host interception and egress host.docker.internal mapping can point at the wrong address and framework routes fail from the container.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 81fed07. Configure here.
| and not runtime.network_access | ||
| and not tunneled | ||
| else None | ||
| ) |
There was a problem hiding this comment.
Shared interception host too early
High Severity
Eval serving() fixes extra_host from docker_interception_host() before any rollout creates its setup network, and every rollout shares that single bind address. Per-rollout bridge gateways differ, so shared interception often never listens on the address restricted Docker harnesses use to reach the host.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 81fed07. Configure here.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 81fed07b1a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| url: str | ||
| local: bool | ||
| reaches_host: bool |
There was a problem hiding this comment.
Preserve the shared-tool locality attribute
Renaming this field leaves serve_tools() still reading server.local when attaching non-external shared tool servers to a rollout, so any Taskset.tools shared server launched by the framework now fails before the harness starts with AttributeError: 'SharedToolServer' object has no attribute 'local'. Update the caller to use reaches_host (or keep a compatible property) so shared tools continue to work.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d23b5acf4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if url is None: | ||
| raise SandboxError(f"{service.type} runtime cannot expose port {port}") | ||
| yield url | ||
| elif consumer_reaches_host: # host network, direct consumer → localhost, no tunnel |
There was a problem hiding this comment.
Avoid Prime tunnels for local MCP routes
When the harness is DockerConfig(network_access=False) and a task-scoped or shared MCP tool uses the default non-colocated subprocess runtime, serve() sets consumer_reaches_host to false, so this branch exposes the otherwise local host tool via PrimeTunnel and the Docker sidecar whitelists that public URL. Even after the interception route is kept local, Docker-only offline evals with default host tools still fail on hosts without prime_tunnel credentials or external egress; local framework tool servers need a Docker-bridge/local URL path instead of falling through to the public tunnel branch.
Useful? React with 👍 / 👎.
|
superseded by #2024 |


Overview
Preserves the framework routes required by an offline Docker harness while denying arbitrary agent egress. Trusted setup retains ordinary network access; after setup, the runtime moves to an isolated execution network for the remainder of its lifetime.
Details
Note
Preserve interception for offline Docker agents by routing egress through a restricted network
network_access: booltoDockerConfig(docker.py); whenFalse, the agent container is isolated from arbitrary egress after setup and all framework routes are proxied through a local nginx egress container on an isolated execution network.docker_interception_host()to resolve the Linux bridge gateway IP so the interception server can bind an extra host address reachable from within the restricted container.InterceptionServer,StaticInterceptionPool, andElasticInterceptionPool(server.py, pool.py) to accept anextra_hostparameter and bind on multiple local addresses simultaneously when not tunneling.runtime_is_localwithruntime_reaches_host_locallythroughout MCP launch and interception logic to correctly distinguish runtimes that need tunnels from those that reach host services directly.apply_network_policyto theRuntimebase class (base.py);Rollout.runcalls it after resolving endpoints so the harness runtime can rewrite model and MCP URLs before execution.network_access=Falseuse different networks during setup vs. execution; cleanup now removes the egress container and both networks, which may leave resources behind on hard failures.Macroscope summarized 4d23b5a.
Note
High Risk
Changes security-critical Docker network topology, URL rewriting for all harness traffic, and interception binding; misconfiguration could break rollouts or weaken isolation.
Overview
Introduces restricted agent networking for Docker harnesses via
DockerConfig.network_access(default true). When false, setup keeps a normal bridge network; after rollout setup,apply_network_policymoves the agent onto an internal execution network and rewrites model/MCP URLs to per-route nginx egress proxies (egress:8080+N) that only allow the declared paths—arbitrary internet/DNS egress is blocked until teardown.Adds a shared
NetworkPolicy/Runtime.apply_network_policyhook on the base runtime (other backends still error if restricted).Rollout.runpasses named routes (model,mcp:*) through this boundary and rejects colocated MCP/user servers when the harness policy cannot support them.Refactors locality into explicit reachability:
runtime_reaches_host_locally,reaches_host_locally,reachable_from_host_locally, andSharedToolServer.reaches_host(replacinglocal/harness_is_localin tunnel and MCP URL logic). Interception can listen on anextra_host(Docker bridge gateway fromdocker_interception_host) so containers without host loopback still hit/stateand model routes when no public tunnel is used.Tool/user runtimes with a restricted policy cannot be launched standalone (
serveraises);exposefailures now surface asSandboxError.Reviewed by Cursor Bugbot for commit 4d23b5a. Bugbot is set up for automated code reviews on this repo. Configure here.